Skip to content

Fix config-read chunk cap to cover full MAX_CONFIG_SIZE (MJ-14)#8

Open
balloob wants to merge 1 commit into
OpenDisplay:mainfrom
balloob:fix/config-read-cap
Open

Fix config-read chunk cap to cover full MAX_CONFIG_SIZE (MJ-14)#8
balloob wants to merge 1 commit into
OpenDisplay:mainfrom
balloob:fix/config-read-cap

Conversation

@balloob

@balloob balloob commented Jul 6, 2026

Copy link
Copy Markdown

Finding MJ-14 (Silabs side)

The read-config chunk loop in handle_config_read (opendisplay_pipe.c) capped the number of response chunks at a hardcoded max_chunks = 10. Because the cap was a magic number decoupled from MAX_CONFIG_SIZE, any config whose length exceeds the cap's reach can never be fully read: the client loops until it has received total bytes, but the firmware stops sending after the cap, so the client retries/times out indefinitely.

Fix

Derive the cap from MAX_CONFIG_SIZE so a full config is always readable and the cap scales automatically if MAX_CONFIG_SIZE changes:

const uint16_t max_chunks =
    (uint16_t)((MAX_CONFIG_SIZE + (MAX_RESPONSE_DATA_SIZE - 6u) - 1u) /
               (MAX_RESPONSE_DATA_SIZE - 6u));

Chunk 0 carries a 4-byte header plus a 2-byte length prefix (94 payload bytes); later chunks carry only the 4-byte header (96 payload bytes). Sizing against the smallest per-chunk payload (MAX_RESPONSE_DATA_SIZE - 6 = 94) guarantees sufficiency. Per-chunk size and framing are unchanged.

Old vs new max readable size

With MAX_RESPONSE_DATA_SIZE = 100:

  • Old: cap = 10 chunks → 94 + 9×96 = 958 B max readable.
  • New: cap derived from MAX_CONFIG_SIZE → covers the full config by construction.

Note: on the Silabs side MAX_CONFIG_SIZE is currently 512, which is already below the old 958 B reach, so the MJ-14 symptom does not manifest here today — this change is hardening that ties the read cap to MAX_CONFIG_SIZE and removes the fragile magic number. With MAX_CONFIG_SIZE = 512 the derived cap is 6 chunks (574 B raw capacity), still covering the full config. MJ-14 also requires the companion read-cap raises on the nRF and Arduino firmwares, where MAX_CONFIG_SIZE is larger and the bug is live.

Verify

No SLC / arm-none-eabi-gcc / cmake_gcc toolchain available in this environment, so no firmware build. The full file cannot be host-compiled without the Silabs SDK headers (sl_bt_api.h). The isolated cap expression was host-compiled clean under gcc -Wall -Wextra -Wconversion and verified to yield max_chunks = 6 covering 512 B.

🤖 Generated with Claude Code

https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR

The read-config chunk loop used a hardcoded cap of 10 chunks. Because the
cap was a magic number decoupled from MAX_CONFIG_SIZE, a config larger than
the cap's reach could never be fully read: the client loops until it has
`total` bytes and the firmware simply stops sending, so the client
retries/times out forever.

Derive the cap from MAX_CONFIG_SIZE instead, using the smallest per-chunk
payload (MAX_RESPONSE_DATA_SIZE - 6, the chunk-0 size) so it is always
sufficient and scales automatically if MAX_CONFIG_SIZE changes.

Per-chunk size and framing are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant